<?php 
/* --------------------------------
 * Функции по работе с экспортом XML
 *  
 * 9 августа 2012
 * © Deemon 
 --------------------------------*/
 
 	Class UpdatePrice
	{
		private $conn;
		private $elog;
		private $fields;
		private $str_count_product = '';
		private $havent_code_str = '';
		private $count_updated = 0;
		private $errors = array();
		private	$notices = array();
		private $products = array();
		private $return_data = array( 'message' => '', 'codes' => array() );
		private $updated_products = array();
		private $count_updated_fields = 0;
		private $data_for_query = array();
		private $data_for_query_second = array();
		private $updated = array();
		private $havent_codes = array();
		private $db_codes = array();
		private $banners = array();
		private $types = array();
		private $has_null;
		private $cols = array();
		private $xml_pr_codes = array();
		private	$line = 0;
		private	$message = '';
		private	$field = '';
		private	$value = '';
		private	$product_code = '';

		
		function startUpdate( $fine_name, $fields )
		{
			$this->setVariables( $fields );
			$this->readFile( $fine_name );  
			
			if( count( $this->errors ) ) {
				$this->errors[] = 'ТОВАРЫ НЕ БЫЛИ ОБНОВЛЕНЫ!!! НУЖНО ИСПРАВИТЬ ФАЙЛ';
				$this->dispErrors();
				return $this->message;
			}
			
			$this->prepareData();
			$this->startQuery();		
			
 			if( count( $this->updated_products ) )
				updateAll( $this->updated_products );
			
			$this->dispMessage();
			return $this->message;
		}
		
		function setVariables( $fields )
		{
			$this->conn = $GLOBALS['conn'];
			$this->elog = $GLOBALS['elog'];
			
			$new_field = array();
			foreach( $fields as $title => $field ) 
				$new_field[mb_strtolower($title)] = $field;
		
			$this->fields = $new_field;

			foreach( $this->fields as $title => $data )
				$this->types[$data['field']] = $data['type'];

			$this->has_null = array( 'pp', 'price_inst', 'price_vip', 'volume', 'accessories', 'similar', 'corsini_code', 'market_code', 'market_name' );
			
			$this->conn->unquery( 'SELECT `product_code`, `corsini_code` FROM `store_products_view`' );
			while( $row = $this->conn->fetch() )
				$this->db_codes[$row->product_code] = $row->corsini_code ? $row->corsini_code : 0;
		}
		
		private function readFile( $fine_name )
		{
			$file = fopen( $_FILES[$fine_name]['tmp_name'] , 'r' );
			while( ( $datas = fgetcsv( $file, '', ',' ) ) !== FALSE )
			{
				$values = array();
				$datas = array_map( 'trim', array_map( 'iconvWU', $datas ) );
				if( $this->line++ == 0 )
				{
					foreach( $datas as $col => $title )
					{
						if( strlen( $title ) ) {
							$lower_title = mb_strtolower( $title );
							if( isset( $this->fields[$lower_title] ) )
								$this->cols[$col] = array( 'title' => $title, 'field' => $this->fields[$lower_title]['field'], 'type' => $this->fields[$lower_title]['type']  );
							else
								$this->errors[] = 'Не опознан столбец с названием: '.$title;
						}
					}
				}
 				else
				{
					foreach( $datas as $col => $value )
					{
						if( isset( $this->cols[$col] ) && strlen( $value ) )
						{
							if( $this->cols[$col]['type'] == 'int' && $value != 'n' ) {  // Проверка на число
								if( !is_numeric( $value ) )
									$this->errors[] = 'Строка '.$this->line.'. Некорректное значение в поле: '.$this->cols[$col]['title'];
							}
							$values[$this->cols[$col]['field']] = $value;
						}
					}
					
					if( isset( $values['artikul'] ) || isset( $values['corsini'] ) )
					{
						if( isset( $values['artikul'] ) )
						{
							if( isset( $this->db_codes[$values['artikul']] ) )
							{
								$product_code = $values['artikul'];
							}
							else
							{
								$this->notices[] = 'Строка '.$this->line.'. Такого кода нет на сайте: '.$values['artikul'];
								continue;
							}
							unset( $values['artikul'] );
						}
						else 
						{
							if( !( $product_code = array_search( $values['corsini'], $this->db_codes ) ) )
							{
								$this->notices[] = 'Строка '.$this->line.'. Такого Кода Корсини нет на сайте, либо не заведен: '.$values['corsini'];
								continue;
							}
							unset( $values['corsini'] );
						}			
					}
					else
					{
						$this->errors[] = 'Строка '.$this->line.'. Артикул не найден';
					}
					
					if( count( $values ) ) {
						$this->products[$product_code] = $values;
						$this->updated_products[$product_code] = $product_code;
					}
				}
			}
		}
		
		function prepareData()
		{
			foreach( $this->products as $this->product_code => $product )
			{
				foreach( $product as $this->field => $this->value )
				{
					if( $this->field == 'sales_notes' || $this->field == 'phone' ) {
						$xml_data_id = ( $this->value != 'n' ) ? $this->getXmlDataId( $this->field, $this->value ) : 'n';
						$this->xml_pr_codes[$xml_data_id][] = $this->product_code;
						continue;
					}
			
					$this->saveDataForQuery();
					if( $this->field == 'pp' && $this->value == '1' ) {
						$this->field = 'pm';
						$this->saveDataForQuery();
					}
				}
			}
		}
		
		private function saveDataForQuery()
		{
			$value = ( $this->value != 'n' ) ? $this->value : 'NULL';
			$this->data_for_query[$this->field]['value'][] = ( $this->types[$this->field] == 'int' || $value == 'NULL'  ) ? $value :'"'.mysql_real_escape_string( $value ).'"';
			$this->data_for_query[$this->field]['code'][] = $this->product_code;		
		}
		
 		private function startQuery()
		{
 			foreach( $this->data_for_query as $field => $pr )  // Обновляем таблицу товаров
			{
 				$this->conn->query('
					UPDATE `store_products` SET
						'.$field.' = ELT(FIELD( `product_code`, '.implode( $pr['code'], ', ' ).' ), '.implode( $pr['value'], ', ' ).' )
							WHERE `product_code` IN ( '.implode( $pr['code'], ', '  ).' )' );
				$this->count_updated_fields += count( $pr['value'] );
			}
			
			$codes = $values = array();
			foreach( $this->xml_pr_codes as $xml_data_id => $product_codes ) {
				foreach( $product_codes as $product_code ) {
					$codes[] = $product_code;
					if( $xml_data_id != 'n' )
						$values[] = '( '.$xml_data_id.', '.$product_code.' )';
				}
			}
			if( count( $codes ) )  // Удаляем с таблицы связи старые данные, дабы не задвоить далее при добавлении новых
				$this->conn->query('DELETE FROM store_product_xml_data_relation WHERE product_code IN( '.implode( ',', $codes ).' )');
			if( count( $values ) )
				$this->conn->query('INSERT INTO store_product_xml_data_relation ( xml_data_id, product_code ) VALUES '.implode( ',', $values ) );
		}
		
		private function getXmlDataId( $type, $val )
		{
			static $first = true;
			static $store = array();
			
			if( $first )
			{
				$this->conn->query('SELECT * FROM store_product_xml_data WHERE type = type = "'.$type.'"');
				while( $row = $this->conn->fetch() )
					$store[$row->value] = $row->id;			
				$first = false;
			}
			
			if( isset( $store[$val] ) )
				return $store[$val];			
			
			$id = $this->conn->query('INSERT INTO store_product_xml_data SET value = "'.mysql_real_escape_string( $val ).'", type = "'.$type.'"', true);
			$store[$val] = $id;
			return $id;
		}
		
		private function dispErrors()
		{
			if( count( $this->errors ) ) 
			{
				$message = '';
				foreach( $this->errors as $error )
					$message .= $error.'<br />';
				$this->message .= '<span class="red_str">'.$message.'</span>';
			}
		}
		
		private function dispMessage()
		{
			$this->message .= '
				<p>
					<h3 class="green_str">
						Количество обновленных товаров: '.count( $this->updated_products ).'<br/>
						Количество обновленных признаков: '.$this->count_updated_fields.'
					</h3>
				</p>';
				
			if( count( $this->notices ) ) {
				$message = '';
				foreach( $this->notices as $notice )
					$message .= $notice.'<br />';
				$this->message .= '<span class="yellow_str">'.$message.'</span>';
			}
		}
	}
	